added samples
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / CSEncryption / SymmetricAlgorithmsForm.cs
blob7363cb0f12d16282311110c641b49214cbd92ac0
1 /******************************** Module Header ********************************\
2 * Module Name: SymmetricsAlgorithmsForm.cs
3 * Project: CSEncryption
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Symmetric algorithms:
7 * A symmetric algorithm is a cipher in which encryption and decryption use the
8 * same key or keys that are mathematically related to one another in such a
9 * way that it is easy to compute one key from knowledge of the other, which is
10 * effectively a single key.Some symmetric algorithms commonly used are DES,
11 * TripleDES, RC2,RijnDael.
13 * This Form demonstrates how to use DES,RC2,TripleDES and Rijndael to encrypt &
14 * decrypt string. I refer to some code from the book .NET Security and
15 * Cryptography.
17 * Code Logic:
18 * 1 Select one symmetric algorithm
19 * 2 Input the data into textbox so as to create message object
20 * 3 Click encrypt button
21 * 3.1 Serialize the message object to get plaintext data as byte array
22 * 3.2 Encrypt data by using SymmetricAlgorithm Provider
23 * 3.3 Update UI display
24 * 4 Click decrypt button to decrypt) data
25 * 4.1 Create SymmetricAlgorithm Provider and initialize it with key, IV,etc
26 * 4.2 Decrypt ciphered data to get plain text
27 * 4.3 Update UI display
29 * This source is subject to the Microsoft Public License.
30 * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
31 * All other rights reserved.
33 * History:
34 * * 4/10/2009 06:50 PM Riquel Dong Created
35 \*******************************************************************************/
37 #region Using directives
38 using System;
39 using System.Collections.Generic;
40 using System.ComponentModel;
41 using System.Data;
42 using System.Drawing;
43 using System.Linq;
44 using System.Text;
45 using System.Windows.Forms;
46 using System.Security.Cryptography;
47 using System.IO;
48 using System.Runtime.Serialization.Formatters.Binary;
49 #endregion
52 namespace CSEncryption
54 public partial class SymmetricAlgorithmForm : Form
56 // One byte array variable as a key to use for the algorithm
57 byte[] key;
59 // The initialization vector (IV) variable for the symmetric algorithm
60 byte[] initVector;
62 // Specifies the block cipher mode to use for encryption
63 CipherMode cipherMode;
65 // Specifies the type of padding
66 PaddingMode paddingMode;
68 // Byte array to contain ciphered message
69 byte[] cipherBytes;
71 /// <summary>
72 /// Bases on combobox current value to set cipher mode
73 /// </summary>
74 private void SetCipherMode()
76 switch (comboboxMode.Text.Trim())
78 case "ECB":
79 cipherMode = CipherMode.ECB;
80 break;
81 case "CBC":
82 cipherMode = CipherMode.CBC;
83 break;
84 case "CFB":
85 cipherMode = CipherMode.CFB;
86 break;
87 case "OFB":
88 cipherMode = CipherMode.OFB;
89 break;
90 case "CTS":
91 cipherMode = CipherMode.CTS;
92 break;
96 /// <summary>
97 /// Based on combobox current value to set padding mode
98 /// </summary>
99 private void SetPaddingMode()
101 switch (comboboxPadding.Text.Trim())
103 case "PKCS7":
104 paddingMode = PaddingMode.PKCS7;
105 break;
106 case "Zeros":
107 paddingMode = PaddingMode.Zeros;
108 break;
109 default:
110 paddingMode = PaddingMode.None;
111 break;
115 /// <summary>
116 /// Based on user selection to create a cryptographic object to
117 /// perform the according Symmetric algorithm.
118 /// </summary>
119 SymmetricAlgorithm GetSymmetricAlgorithmProvider()
121 //create new instance of symmetric algorithm
122 if (this.radiobtnRC2.Checked == true)
123 return RC2.Create();
124 if (this.radiobtnRijndael.Checked == true)
125 return Rijndael.Create();
126 if (this.radiobtnDES.Checked == true)
127 return DES.Create();
128 if (this.radiobtnTrippleDES.Checked == true)
129 return TripleDES.Create();
130 return null;
133 /// <summary>
134 /// Generates a random key (Key) to use for the algorithm
135 /// </summary>
136 private void GenRandomKey()
138 // Generate new random IV
139 SymmetricAlgorithm sa =
140 GetSymmetricAlgorithmProvider();
141 sa.GenerateKey();
142 key = sa.Key;
144 // Do UI stuff
145 UpdateKeyTextBox();
146 ClearOutputFields();
149 /// <summary>
150 /// Display key in textbox control
151 /// </summary>
152 private void UpdateKeyTextBox()
154 StringBuilder sb = new StringBuilder();
155 for (Int32 i = 0; i < key.Length; i++)
157 sb.Append(string.Format("{0:X2} ", key[i]));
159 this.tbxRandomKey.Text = sb.ToString();
162 /// <summary>
163 /// Display IV in textbox control
164 /// </summary>
165 private void UpdateIVTextBox()
167 StringBuilder sb = new StringBuilder();
168 for (Int32 i = 0; i < initVector.Length; i++)
170 sb.Append(string.Format("{0:X2} ", initVector[i]));
172 this.tbxRandomInitVector.Text = sb.ToString();
175 /// <summary>
176 /// Clear output value in textbox
177 /// </summary>
178 private void ClearOutputFields()
180 tbxIntegerPart.Text = string.Empty;
181 tbxMessagePart.Text = string.Empty;
182 tbxcipherTextasByteArray.Text = string.Empty;
183 tbxPlaintextasBytesArray.Text = string.Empty;
186 /// <summary>
187 /// Generates a random IV to use for the algorithm
188 /// </summary>
189 private void GenRandomIV()
191 // Generate new random IV
192 SymmetricAlgorithm sa =
193 GetSymmetricAlgorithmProvider();
194 sa.GenerateIV();
195 initVector = sa.IV;
197 // Do UI stuff
198 UpdateIVTextBox();
199 ClearOutputFields();
202 public SymmetricAlgorithmForm()
204 InitializeComponent();
207 private void SymmetricAlgorithmForm_Load(object sender, EventArgs e)
209 // Populate the combobox for cipher mode
210 comboboxMode.Items.AddRange(new
211 object[] { "ECB", "CBC", "CFB", "OFB", "CTS" });
212 comboboxMode.SelectedIndex = 1;
214 // Populate the combobox to specify padding mode
215 comboboxPadding.Items.AddRange(new object[] { "PKCS7", "Zeros", "None" });
216 comboboxPadding.SelectedIndex = 1;
218 // Set TextBox to readonly to prevent editting
219 tbxcipherTextasByteArray.ReadOnly = true;
220 tbxPlaintextasBytesArray.ReadOnly = true;
221 radiobtnDES.Checked = true;
222 GenRandomIV();
223 GenRandomKey();
225 // Specifies cipher mode
226 SetCipherMode();
228 // Specifies padding mode
229 SetPaddingMode();
230 btnDecrypt.Enabled = false;
233 private void btnNewRandomKey_Click(object sender, EventArgs e)
235 // Generates a random key (Key) to use for the algorithm
236 GenRandomKey();
237 ClearOutputFields();
238 btnDecrypt.Enabled = false;
239 btnEncrypt.Enabled = true;
242 private void btnNewRandomInitVector_Click(object sender, EventArgs e)
244 // Generates a random initialization vector (IV)
245 GenRandomIV();
246 ClearOutputFields();
247 btnDecrypt.Enabled = false;
248 btnEncrypt.Enabled = true;
251 private void btnEncrypt_Click(object sender, EventArgs e)
253 int number = 0;
254 if (string.IsNullOrEmpty(tbxInputMessage.Text) ||
255 !int.TryParse(tbxInputInterger.Text, out number))
257 MessageBox.Show("Invalid parameters!");
258 return;
261 // Clear textbox control so as to display new output
262 ClearOutputFields();
263 Message msg = new Message();
264 msg.Num = number;
265 msg.MessageBody = tbxInputMessage.Text.Trim();
269 /////////////////////////////////////////////////////////////////
270 // Create a cryptographic provider object
273 SymmetricAlgorithm sa = GetSymmetricAlgorithmProvider();
274 // Sets the secret key for the symmetric algorithm
275 sa.Key = key;
276 // Sets the IV for the symmetric algorithm
277 sa.IV = initVector;
278 // Sets the mode for operation of the symmetric algorithm
279 sa.Mode = cipherMode;
280 // Sets the padding mode used in the symmetric algorithm
281 sa.Padding = paddingMode;
284 /////////////////////////////////////////////////////////////////
285 // Serialize message object to get plain text
287 BinaryFormatter bf = new BinaryFormatter();
288 byte[] plainBytes;
289 using (MemoryStream stream = new MemoryStream())
291 bf.Serialize(stream, msg);
292 plainBytes = stream.ToArray();
296 /////////////////////////////////////////////////////////////////
297 // Encryt plaintext to get ciphered data
300 // Defines a stream object to get ciphered data
301 MemoryStream ms = new MemoryStream();
303 // Defines a stream for cryptographic transformations
304 CryptoStream cs = new CryptoStream(ms,
305 sa.CreateEncryptor(), CryptoStreamMode.Write);
307 // Writes a sequence of bytes for encrption
308 cs.Write(plainBytes, 0, plainBytes.Length);
310 // Closes the current stream and releases any resources
311 cs.Close();
312 // Save the ciphered message into one byte array
313 cipherBytes = ms.ToArray();
314 // Closes the memorystream object
315 ms.Close();
318 /////////////////////////////////////////////////////////////////
319 // Display ciphered message in textbox control as byte array
322 StringBuilder sb = new StringBuilder();
323 for (Int32 i = 0; i < cipherBytes.Length; i++)
325 sb.Append(string.Format("{0:X2} ", cipherBytes[i]));
327 tbxcipherTextasByteArray.Text = sb.ToString();
329 // Display plaintext as a byte array in textbox control
330 sb = new StringBuilder();
331 for (Int32 i = 0; i < plainBytes.Length; i++)
333 sb.Append(string.Format("{0:X2} ", plainBytes[i]));
335 tbxPlaintextasBytesArray.Text = sb.ToString();
337 //update UI
338 radiobtnDES.Enabled = false;
339 radiobtnTrippleDES.Enabled = false;
340 radiobtnRC2.Enabled = false;
341 radiobtnRijndael.Enabled = false;
343 comboboxMode.Enabled = false;
344 comboboxPadding.Enabled = false;
345 btnNewRandomInitVector.Enabled = false;
346 btnNewRandomKey.Enabled = false;
347 btnEncrypt.Enabled = false;
348 btnDecrypt.Enabled = true;
350 catch (Exception ex)
352 // Display the error information to user
353 MessageBox.Show(ex.Message);
357 private void btnDecrypt_Click(object sender, EventArgs e)
361 /////////////////////////////////////////////////////////////////
362 // Create a cryptographic provider object used to decrypt data
365 SymmetricAlgorithm sa = GetSymmetricAlgorithmProvider();
366 // Sets the secret key
367 sa.Key = key;
368 // Sets the IV
369 sa.IV = initVector;
370 // Sets the mode
371 sa.Mode = cipherMode;
372 // Sets the padding mode
373 sa.Padding = paddingMode;
376 /////////////////////////////////////////////////////////////////
377 // Decrypt ciphered data to get plain text
380 byte[] plainbytes;
381 // Defines a stream object to contain the decrypted data
382 using (MemoryStream ms = new MemoryStream(cipherBytes))
384 // Defines a stream for cryptographic transformations
385 using (CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(),
386 CryptoStreamMode.Read))
388 // Defines one byte array for recovered plaintext
389 plainbytes = new byte[cipherBytes.Length];
390 // Reads a sequence of bytes for decryption
391 cs.Read(plainbytes, 0, cipherBytes.Length);
396 /////////////////////////////////////////////////////////////////
397 // Deserialize data to get message object and display it in UI
400 Message recoveredMessage;
401 using (MemoryStream stream = new MemoryStream(plainbytes, false))
403 BinaryFormatter bf = new BinaryFormatter();
404 recoveredMessage = (Message)bf.Deserialize(stream);
407 // Display the recovered message in textbox control
408 this.tbxIntegerPart.Text = recoveredMessage.Num.ToString();
409 this.tbxMessagePart.Text = recoveredMessage.MessageBody;
411 // Update UI
412 comboboxMode.Enabled = true;
413 comboboxPadding.Enabled = true;
414 btnNewRandomInitVector.Enabled = true;
415 btnNewRandomKey.Enabled = true;
416 radiobtnDES.Enabled = true;
417 radiobtnTrippleDES.Enabled = true;
418 radiobtnRC2.Enabled = true;
419 radiobtnRijndael.Enabled = true;
420 btnEncrypt.Enabled = true;
421 btnDecrypt.Enabled = false;
423 catch (Exception ex)
425 MessageBox.Show(ex.Message);
429 /// <summary>
430 /// Based on user seleciton to create a cryptographic object to perform
431 /// the according Symmetric algorithm
432 /// </summary>
433 private void radiobtnSymmetricAlgorithm_CheckedChanged(object sender, EventArgs e)
435 if (((RadioButton)sender).Checked)
437 SymmetricAlgorithm sa = GetSymmetricAlgorithmProvider();
438 key = sa.Key;
439 initVector = sa.IV;
440 UpdateKeyTextBox();
441 UpdateIVTextBox();
442 ClearOutputFields();
446 private void comboboxMode_SelectedIndexChanged(object sender, EventArgs e)
448 SetCipherMode();
451 private void comboboxPadding_SelectedIndexChanged(object sender, EventArgs e)
453 SetPaddingMode();
456 private void tbxInputInterger_TextChanged(object sender, EventArgs e)
458 ClearOutputFields();
459 btnDecrypt.Enabled = false;
460 btnEncrypt.Enabled = true;
463 private void tbxInputMessage_TextChanged(object sender, EventArgs e)
465 ClearOutputFields();
466 btnDecrypt.Enabled = false;
467 btnEncrypt.Enabled = true;
472 [Serializable]
473 public class Message
475 private string _messageBody;
476 private int _num;
477 public string MessageBody
479 get { return _messageBody; }
480 set { _messageBody = value; }
482 public int Num
484 get { return _num; }
485 set { _num = value; }